import pandas as pd
from itertools import combinations
from collections import defaultdict

class Apriori:
    def __init__(self, min_support):
        self.min_support = min_support
        self.frequent_itemsets = []  
        self.support_data = {} 
    def fit(self, transactions):
        current_itemsets = self.get_frequent_1_itemsets(transactions)
        k = 1

        while current_itemsets:
            for itemset in current_itemsets:
                self.frequent_itemsets.append((itemset, self.support_data[itemset]))

            k += 1
            current_itemsets = self.get_frequent_itemsets(transactions, current_itemsets, k)

    def get_frequent_1_itemsets(self, transactions):
        item_count = defaultdict(int)
        for transaction in transactions:
            for item in transaction:
                item_count[item] += 1
        total_transactions = len(transactions)
        self.support_data = {frozenset([item]): count / total_transactions for item, count in item_count.items() if count / total_transactions >= self.min_support}
        return set(self.support_data.keys())

    def get_frequent_itemsets(self, transactions, current_itemsets, k):
        candidates = set()
        current_itemsets = list(current_itemsets)
        for i in range(len(current_itemsets)):
            for j in range(i + 1, len(current_itemsets)):
                candidate = current_itemsets[i] | current_itemsets[j] 
                if len(candidate) == k:  
                    candidates.add(candidate)

        item_count = defaultdict(int)
        total_transactions = len(transactions)

        for transaction in transactions:
            transaction_set = set(transaction)
            for candidate in candidates:
                if candidate.issubset(transaction_set):
                    item_count[candidate] += 1
        for candidate, count in item_count.items():
            if count / total_transactions >= self.min_support:
                self.support_data[candidate] = count / total_transactions

        return {frozenset(itemset) for itemset in item_count if count / total_transactions >= self.min_support}

if __name__ == '__main__':
    iris_data = pd.read_csv('iris.csv', header=None)
    
    transactions = []
    for _, row in iris_data.iterrows():
        transactions.append(set(row[:-1].astype(str).values)) 

   
    min_support = 0.1
    apriori = Apriori(min_support)

   
    apriori.fit(transactions)

    
    print("频繁项集及其支持度:")
    for itemset, support in apriori.frequent_itemsets:
        print(f"{set(itemset)}: {support:.4f}")